package org.windowkit.toolkit.widget.combo;

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Comparator;

import org.ddevil.data.Data;
import org.ddevil.data.set.DataSet;


/**
 * A combo box that is backed by a DataSet object.
 * The attribute from the Data Set that will be used as the label is set
 * with {@link #setDisplayID(String)}.  The attribute that will be returned
 * when getValues() is called can be set using {@link #setDataDBID(String)}.
 * You can access the entire Data object that backs a particular option
 * as well, {@link #getSelectedData()}.
 * <p>
 *
 * @see {@link org.ddevil.data.set.DataSet}
 *
 * @author Rich O'Connell
 *
 */
public class DataSetComboBox extends AbstractComboBoxField {
	private static final long serialVersionUID = -2460851136608835123L;

	/** The DB Id of the attribute that will be returned when getValues() is called. */
    protected String mainDataDbId;

    public DataSetComboBox(final String displayID){
        this(null, displayID, null, false, null, 10);
    }

    public DataSetComboBox(final String displayID, final String mainDataId){
        this(null, displayID, mainDataId, false, null, 10);
    }

    public DataSetComboBox(final DataSet data, final String displayID, final String dataID, final boolean isEditable,
            final String defaultOption, final int textWidth){
        super(createModel(data, displayID), isEditable, defaultOption, textWidth);

        this.mainDataDbId = dataID;
    }

    private static DataSetComboModel createModel(final DataSet data, String displayId){
        if(displayId == null) {
			displayId = "";
		}
        if(data == null) {
			return new DataSetComboModel(displayId);
		}
		else {
			return new DataSetComboModel(data, displayId);
		}
    }

    protected DataSetComboModel getModel(){
        return (DataSetComboModel)model;
    }

    /**
     * Set the DataSet that backs this combo box.
     *
     * @param data
     *          The DataSet model.
     * @param id
     *          The DB Id of the attribute to use as the label.
     */
    public void setData(final DataSet data, final String id) {
        getModel().setDataSet(data, id);
    }

    public void setData(final DataSet data){
        getModel().setDataSet(data);
    }

    /**
     * Set the ID of the attribute in our data set that will be displayed
     * as the label.
     *
     * @param id
     *      The ID of the attribute that should be seen.
     */
    public void setDisplayID(final String id) {
        getModel().setDisplayID(id);
    }

    /**
     * Set the DB Id of the attribute that should be returned
     * from this combos data set backing when getValues() is called.
     * This is the Object that will be returned during the automated
     * attribute gathering process.
     *
     * @param id
     */
    public void setDataDBID(final String id){
        this.mainDataDbId = id;
    }


    /**
     * Get the data which backs the currently selected option.
     * @return The data backing the currently selected option.
     */
    public Data getSelectedData() {
        return getModel().getSelectedData();
    }

    /**
     * Add and item to the combobox.
     */
    public void addItem(final Data item) {
        getModel().addData(item);
    }

    /**
     * Add multiple items to the comboBox
     */
    public void addItems(final DataSet in) {
        for(int i = 0; i < in.size(); i++){
            addItem(in.exportRecord(i));
        }
    }

    /**
     * @return the selected value.
     */
    public Object getSelectedValue() {
         Object ret = null;
        if(mainDataDbId != null){
            Data rec = getModel().getSelectedData();
            if(rec != null){
                ret = rec.getValue(mainDataDbId);
            }
        }else{
            ret = getModel().getSelectedItem();
        }
        return ret;
    }


    @Override
    protected ItemListener createEditItemListener() {
        return new ItemListener() {
            public void itemStateChanged(final ItemEvent evt) {
                if (getModel().getIndexOf(evt.getItem()) == -1) {
                    getModel().addElement(evt.getItem());
                }
            }
        };
    }

    /**
     * Set the comparator to use when sorting the labels.
     *
     * @param c
     */
    public void setLabelComparator(final Comparator c){
        getModel().setLabelComparator(c);
    }

}
